module Madly #:nodoc:
  module TimeComparisons
    # Returns true if receiver is chronologically before a Time, Date or DateTime object
    def before?(other)
      self.compare_time(other) == -1
    end

    # Returns true if receiver is chronologically after a Time, Date or DateTime object
    def after?(other)
      self.compare_time(other) == 1
    end

    # Returns true if receiver is chronologically equal to a Time, Date or DateTime object
    def same_time?(other)
      self.compare_time(other) == 0
    end

    # Returns true if receiver is chronologically equal to or before a Time, Date or DateTime object
    def same_time_or_before?(other)
      result = self.compare_time(other) 
      result == -1 || result == 0
    end

    # Returns true if receiver is chronologically equal to or after a Time, Date or DateTime object
    def same_time_or_after?(other)
      result = self.compare_time(other) 
      result == 1 || result == 0
    end

    # Returns true if receiver is chronologically equal to or after start, and equal to or before end
    # (or before and not equal to end if final argument is set to true)
    # Arguments can be Time, Date or DateTime objects
    def within?(first, last, exclusive=false)
      end_method = exclusive ? 'before?' : 'same_time_or_before?'
      self.same_time_or_after?(first) && self.__send__(end_method, last)
    end

    # Returns opposite of within? method
    def outside?(first, last, exclusive=false)
      !self.within?(first, last, exclusive)
    end

    # Allows chronological comparisons between Time, Date and DateTime objects. Returns -1, 0 or 1, like <=> operator
    def compare_time(other)
      case other
        when ::Time
          ::Time === self ? self <=> other : self <=> other.to_datetime
        when ::Date
          ::Date === self ? self <=> other : self.to_datetime <=> other
        else 
          raise ArgumentError, "can't compare #{self.class} with #{other.class}"  
      end               
    end
  end
end